﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace DataAccess
{
    public class SqlEventArgs : EventArgs
    {
        public UInt32 UesrID;
        public Type CommandType;
    }
    public class ExcuteSqlEventArgs : SqlEventArgs
    {
        public object _returnValue;
    }
    public class ExcuteSqlArrayEventArgs : SqlEventArgs
    {
        public object[] _returnValue;
    }
    public delegate void ExcuteSqlEventHander(object sender, ExcuteSqlEventArgs e);
    public delegate void ExcuteSqlArrayEventHander(object sender, ExcuteSqlArrayEventArgs e);

    public enum ProcedureType
    {
        EXCUTE_SQL_7_PARAM,
        EXCUTE_SQL_4_PARAM,
        GET_INT_VALUE,
        GET_DS_VALUE_NOPARAM,
        GET_DS_VALUE_PARAM,
        GET_OBJARRAY_VALUE_PARAM,
        GET_OBJARRAY_VALUE_NOPARAM,
        GET_OBJ_VALUE,
    }
    public class BaseParamter
    {
        public UInt32 UserID;
        public ExcuteSqlEventHander completeEvent;
        public ExcuteSqlArrayEventHander completeArrayEvent;
        public ProcedureType _procedureType;
        public string commandText;
        public CommandType commandType;

        public string[] paras;
        public object[] values;
        public string para;
        public object value;
        public SqlDbType type;
        public int tableName;
    }

    /// <summary>
    /// 数据连接池，将所该用户的数据库请求都放在该池中，再依次遍历池内连接请求
    /// </summary>
    public class DataLinkPool
    {
        private event EventHandler ProcessPool;
        private List<BaseParamter> linkPool;
        private bool DataLock = false;
        public DataLinkPool()
        {
            linkPool = new List<BaseParamter>();
            //ProcessPool += new EventHandler(DataLinkPool_ProcessPool);
        }

        public void DataLinkPool_ProcessPool(object sender, EventArgs e)
        {
            ExcutePoolCommand();
            //throw new NotImplementedException();
        }
       
        private static DataLinkPool thisInstance;
       
        public int GetPoolCount()
        {
            return linkPool.Count;
        }

        public void AddCommandInPool(UInt32 name,BaseParamter param)
        {
            linkPool.Add(param);
          //  ProcessPool(null, null);
        }
        private bool _removeCommandFromPool(BaseParamter param)
        {
            if (linkPool == null)
            {
                return false;
            }
            if (linkPool.Count == 0 )
            {
                return false;
            }
            DataLock = true;
            bool ret = linkPool.Remove(param);
            DataLock = false;
            return ret;
        }
        /// <summary>
        /// 处理数据库请求，处理一个删除一个。
        /// </summary>
        public void ExcutePoolCommand()
        {
            if (linkPool.Count == 0)
            {
                return;
            }
            int poolIndex = 0;
            int poolCount = linkPool.Count;
            List<BaseParamter> lis = new List<BaseParamter>(linkPool);
            foreach (BaseParamter p in lis)
            {
                DataLock = true;
                poolIndex++;
                if (p._procedureType == ProcedureType.EXCUTE_SQL_4_PARAM)
                {
                    BaseParamter normal = p;
                    int returnValue = data.executesql(normal.commandText, normal.commandType, normal.paras, normal.values);
                    object sender = this;
                    ExcuteSqlEventArgs e = new ExcuteSqlEventArgs();
                    e._returnValue = returnValue;
                    e.UesrID = p.UserID;
                    if (p.completeEvent != null)
                    {
                        p.completeEvent(sender, e);
                    }
                    DataLock = false;
                    _removeCommandFromPool(p);
                }
                else if (p._procedureType == ProcedureType.EXCUTE_SQL_7_PARAM)
                {
                    BaseParamter normal5 = p;
                    int returnValue = data.executesql(normal5.commandText, normal5.commandType, normal5.paras, normal5.values, normal5.para, out normal5.value, normal5.type);
                    object sender = this;
                    ExcuteSqlEventArgs e = new ExcuteSqlEventArgs();
                    e._returnValue = normal5.value;
                    e.UesrID = p.UserID;
                    if (p.completeEvent != null)
                    {
                        p.completeEvent(sender, e);
                    }
                    DataLock = false;
                    _removeCommandFromPool(p);
                }
                else if (p._procedureType == ProcedureType.GET_DS_VALUE_NOPARAM)
                {
                    BaseParamter tabmem = p;
                    DataSet ds = data.GetDataSet(tabmem.commandText, tabmem.tableName, tabmem.commandType);
                    object sender = this;
                    ExcuteSqlEventArgs e = new ExcuteSqlEventArgs();
                    e._returnValue = ds;
                    e.UesrID = p.UserID;
                    if (p.completeEvent != null)
                    {
                        p.completeEvent(sender, e);
                    }
                    DataLock = false;
                    _removeCommandFromPool(p);
                }
                else if (p._procedureType == ProcedureType.GET_DS_VALUE_PARAM)
                {
                    BaseParamter tabmem3 = p;
                    DataSet ds = data.GetDataSet(tabmem3.commandText, tabmem3.tableName, tabmem3.commandType); 
                    object sender = this;
                    ExcuteSqlEventArgs e = new ExcuteSqlEventArgs();
                    e._returnValue = ds;
                    e.UesrID = p.UserID;
                    if (p.completeEvent != null)
                    {
                        p.completeEvent(sender, e);
                    }
                    DataLock = false;
                    _removeCommandFromPool(p);
                }
                else if (p._procedureType == ProcedureType.GET_INT_VALUE)
                {
                    BaseParamter normal = p;
                    int returnValue = data.GetINTValues(normal.commandText, normal.commandType, normal.paras, normal.values);
                    object sender = this;
                    ExcuteSqlEventArgs e = new ExcuteSqlEventArgs();
                    e._returnValue = returnValue;
                    e.UesrID = p.UserID;
                    if (p.completeEvent != null)
                    {
                        p.completeEvent(sender, e);
                    }
                    DataLock = false;
                    _removeCommandFromPool(p);
                }
                else if (p._procedureType == ProcedureType.GET_OBJ_VALUE)
                {
                    BaseParamter norm = p;
                    object returnValue = data.GetValues(norm.commandText, norm.commandType, norm.paras, norm.values);
                    object sender = this;
                    ExcuteSqlEventArgs e = new ExcuteSqlEventArgs();
                    e._returnValue = returnValue;
                    e.UesrID = p.UserID;
                    if (p.completeEvent != null)
                    {
                        p.completeEvent(sender, e);
                    }
                    DataLock = false;
                    _removeCommandFromPool(p);
                }
                else if (p._procedureType == ProcedureType.GET_OBJARRAY_VALUE_NOPARAM)
                {
                    BaseParamter bsm = (BaseParamter)p;
                    object[] returnValue = data.GetValues(bsm.commandText, bsm.commandType);
                    object sender = this;
                    ExcuteSqlArrayEventArgs e = new ExcuteSqlArrayEventArgs();
                    e._returnValue = returnValue;
                    e.UesrID = p.UserID;
                    if (p.completeArrayEvent != null)
                    {
                        p.completeArrayEvent(sender, e);
                    }
                    DataLock = false;
                    _removeCommandFromPool(p);
                }
                else if (p._procedureType == ProcedureType.GET_OBJARRAY_VALUE_PARAM)
                {
                    BaseParamter norm5 = p;
                    object[] returnValue = data.GetValues(norm5.commandText, norm5.commandType, norm5.paras, norm5.values, norm5.type);
                    object sender = this;
                    ExcuteSqlArrayEventArgs e = new ExcuteSqlArrayEventArgs();
                    e._returnValue = returnValue;
                    e.UesrID = p.UserID;
                    if (p.completeArrayEvent != null)
                    {
                        p.completeArrayEvent(sender, e);
                    }
                    DataLock = false;
                    _removeCommandFromPool(p);
                }
                
                if (poolIndex == poolCount)
                {
                    break;
                }
            }
        }

    }
}
